package com.hmy.contract.service.contract.save.lease.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hmy.ccp.common.dto.ContextUserInfo;
import com.hmy.ccp.error.exception.HMYRuntimeException;
import com.hmy.ccp.starter.web.utils.UserContextUtil;
import com.hmy.contract.common.constant.ContractConstants;
import com.hmy.contract.common.constant.RedisKeyConstants;
import com.hmy.contract.common.properties.LessorInfoProperties;
import com.hmy.contract.common.utils.CommonCodeGenerator;
import com.hmy.contract.commons.enums.ContractBusinessTypeEnum;
import com.hmy.contract.commons.enums.ContractStatusEnum;
import com.hmy.contract.dal.mapper.ContractMapper;
import com.hmy.contract.dal.po.ContractPo;
import com.hmy.contract.manager.order.OrderFeignClientManager;
import com.hmy.contract.manager.worklfow.FlowProcessClientManager;
import com.hmy.contract.service.contract.IContractConfigService;
import com.hmy.contract.service.contract.save.lease.ISaveLeaseContractService;
import com.hmy.contract.service.dto.contract.ContractConfigDto;
import com.hmy.contract.service.dto.contract.OrderPrimaryAndSupplyDto;
import com.hmy.contract.service.dto.save.SaveLeaseContractDto;
import com.hmy.contract.service.rdto.ContractRdto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author seven.qi 齐胜南
 * @version 1.0
 * @description
 * @date 2024/3/11 15:33
 */
@Service
@Slf4j
public class SaveElectronicLeaseContractService extends SaveLeaseContractBaseService implements ISaveLeaseContractService {

    private static final String AREA_MANAGER = "AREA_MANAGER";

    @Value("${process.definition.id}")
    private String processDefinitionId;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private ContractMapper contractMapper;

    @Resource
    private LessorInfoProperties lessorInfoProperties;

    @Resource
    private IContractConfigService contractConfigService;

    @Resource
    private LeaseContractFieldBuildService leaseContractFieldBuildService;

    @Resource
    private FlowProcessClientManager flowProcessClientManager;

    @Resource
    private OrderFeignClientManager orderFeignClientManager;

    @Override
    public void beforeCreate(SaveLeaseContractDto dto) {
        // 防止多次提交订单数据
        LambdaQueryWrapper<ContractPo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ContractPo::getOrderId, dto.getOrderId());
        wrapper.eq(ContractPo::getIsDeleted, Boolean.FALSE);
        wrapper.in(ContractPo::getBusinessType, ContractBusinessTypeEnum.SALE_ELECTRONIC_CONTRACT.getType(), ContractBusinessTypeEnum.SALE_PAPER_CONTRACT.getType());
        List<ContractPo> list = contractMapper.selectList(wrapper);
        if (CollUtil.isNotEmpty(list)) {
            throw new HMYRuntimeException(502000030);
        }

    }

    @Override
    public ContractPo save(SaveLeaseContractDto dto) {
        ContractPo contractPo = convertPo(dto);
        contractMapper.insert(contractPo);
        return contractPo;
    }

    @Override
    public void afterCreate(SaveLeaseContractDto dto) {
        // todo 发起流程，改为最新的流程
        ContractRdto contractRdto = dto.getContractRdto();


        // 调用修改订单状态接口
        try {
            notifyOrder(contractRdto.getContractNo(), contractRdto.getOrderId());
        } catch (Exception e) {
            log.error("notifyOrder exception", e);
        }

    }

    @Override
    public String generateContractNo(SaveLeaseContractDto dto) {
        return CommonCodeGenerator.getNextCode(redisTemplate, ContractConstants.ELECTRONIC_CONTRACT_PREFIX, RedisKeyConstants.CONTRACT_CODE_QUEUE);
    }



//    private void saveProcessInfo(StartProcessInstanceResponse startProcessInstanceResponse, ContractRdto contractPo) {
//        ContextUserInfo currentUser = UserContextUtil.getCurrentUser();
//        ContractProcessStartRequest contractProcessStartRequest = new ContractProcessStartRequest();
//        contractProcessStartRequest.setContractId(contractPo.getContractId());
//        contractProcessStartRequest.setContractProcessId(Long.parseLong(startProcessInstanceResponse.getProcessInstanceId()));
//        contractProcessStartRequest.setContractProcessDefinitionId(processDefinitionId);
//        contractProcessStartRequest.setCurrentActorName(currentUser.getNickName());
//        contractProcessStartRequest.setContractProcessName(contractPo.getContractName());
//        contractProcessStartRequest.setContractProcessTaskId(Long.parseLong(startProcessInstanceResponse.getTaskId()));
//        contractProcessStartRequest.setTaskCandidate(AREA_MANAGER);
//        contractProcessService.startProcess(contractProcessStartRequest);
//    }

//    private StartProcessInstanceResponse startProcess(ContractRdto contractRdto) {
//        StartProcessInstanceRequest startProcessInstanceRequest = new StartProcessInstanceRequest();
//        startProcessInstanceRequest.setProcessDefinitionId(processDefinitionId);
//        Map<String, Object> params = new HashMap<>();
//        params.put("skipCreate", "true");
//        params.put("command", "create");
//        startProcessInstanceRequest.setUserId(UserContextUtil.getCurrentUserId());
//        startProcessInstanceRequest.setProcessVariables(params);
//        FeignResult<StartProcessInstanceResponse> start = null;
//        try {
//            start = flowProcessClientManager.start(startProcessInstanceRequest);
//        } catch (Exception e) {
//            log.error("start process exception", e);
//            throw new HMYRuntimeException(502000004);
//        }
//        return start.getData();
//    }


    private ContractPo convertPo(SaveLeaseContractDto dto) {
        ContractConfigDto contractConfigDto = contractConfigService.checkConfigExist(ContractBusinessTypeEnum.SALE_ELECTRONIC_CONTRACT.getType());
        ContractPo contractPo = new ContractPo();
        OrderPrimaryAndSupplyDto orderInfo = dto.getOrderInfo();
        contractPo.setContractName(contractConfigDto.getContractName());
        contractPo.setContractType(dto.getType());
        contractPo.setContractFileName(contractConfigDto.getContractName());
        contractPo.setProjectName(orderInfo.getProjectName());
        contractPo.setLessorInfo(JSONUtil.toJsonStr(lessorInfoProperties));
        contractPo.setLessorName(lessorInfoProperties.getName());
        ContextUserInfo currentUser = UserContextUtil.getCurrentUser();
        contractPo.setSaleManagerId(currentUser.getId());
        contractPo.setSaleManagerName(currentUser.getUserName());
        if (CollUtil.isNotEmpty(currentUser.getDeptIds())) {
            contractPo.setDeptId(UserContextUtil.getCurrentUserDefaultDeptId());
        }
        contractPo.setOrderId(orderInfo.getOrderId());
        contractPo.setOrderNo(orderInfo.getOrderNo());
        contractPo.setOrderDetailExtension(JSONUtil.toJsonStr(orderInfo));
        contractPo.setCustomerId(orderInfo.getCustomerId());
        contractPo.setCustomerName(orderInfo.getCustomerName());
        contractPo.setCustomerPhone(orderInfo.getCustomerContactorPhone());
        contractPo.setCustomerIdCardNo(orderInfo.getCustomerContactorIdCardNumber());
        contractPo.setCustomerExtension(JSONUtil.toJsonStr(convertToCustomerExtension(orderInfo)));
        contractPo.setAuthorizerInfo(JSONUtil.toJsonStr(orderInfo.getAuthorizerDetails()));
        contractPo.setContractNo(dto.getContractNo());
        contractPo.setStatus(ContractStatusEnum.WAITING_CREATE.getStatus());
        contractPo.setBusinessType(ContractBusinessTypeEnum.SALE_ELECTRONIC_CONTRACT.getType());
        contractPo.setRelationNo(orderInfo.getOrderNo());
        contractPo.setRelationId(orderInfo.getOrderId());
        contractPo.setActorDetailExtension(addLeaseContractActorDetail(dto));
        contractPo.setTemplateDataDetailExtension(addTemplateDataDetailExtension(dto));
        contractPo.setCreatorId(currentUser.getId());
        UserContextUtil.initUpdaterInfo(contractPo);
        UserContextUtil.initCreatorInfo(contractPo);
        return contractPo;
    }


}
